#pragma once
#include <opencv2/opencv.hpp>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>

class ImageBuffer {
public:
    struct Metrics {
        double write_fps;
        double read_fps;
        uint64_t dropped_frames;
    };

    // 构造函数
    explicit ImageBuffer(double metrics_window_duration = 5.0);

    void write(const cv::Mat& image);
    bool read(cv::Mat& output, int timeout_ms = 100);
    Metrics get_metrics() const;

private:
    struct MetricsInternal {
        std::chrono::steady_clock::time_point last_write_time;
        std::chrono::steady_clock::time_point last_read_time;
        std::chrono::steady_clock::time_point window_start_time;
        uint64_t write_count_window = 0;
        uint64_t read_count_window = 0;
        uint64_t dropped_frames = 0;
        double window_duration_seconds;

        explicit MetricsInternal(double window_duration = 5.0)
            : window_duration_seconds(window_duration),
              window_start_time(std::chrono::steady_clock::now()) {}
    };

    std::atomic<int> write_idx_;
    std::atomic<int> read_idx_;
    std::atomic<bool> new_frame_ready_;
    cv::Mat buffers_[2];
    
    std::mutex write_mutex_;
    std::mutex read_mutex_;
    std::mutex swap_mutex_;
    std::condition_variable frame_cv_;
    
    MetricsInternal metrics_;

    void swap_indices();
}; 